Installation

Basic Usage

Expression

Angular use {{ … }} as basic expression

{{ "Hello World" }}  //网页会显示 Hello World

{{ 1+1 }} //网页会显示2

{{ 'a' + 'bc' }} //网页会显示abc

表达式几乎可以用在所有地方,如文本、属性 等等

但是在ng-model, ng-if等标签中传入参数时,是不需要双括号{{}}将参数包裹起来的。

Init ng-app

ng-app 是最基本的Angular wrapper

它可以放在任何tag 上,包括html 和body,如<body ng-app="App">

同时,在app.js 之中,也要相应的声明: var App = angular.module("App", []);

此时,body 里的内容就归属 angular.module("App", []) 管辖范围

Controller ng-controller

此时,在app.js 里新增一个controller

var App = angular.module("App", []);

App.controller('FirstCtrl', function ($scope) {
   $scope.data = {
       message: 'Hello'
   }
});
<body ng-app="App">
    <!-- 将FirstCtrl绑定到这个div标签上,这个标签中的内容将可以使用FirstCtrl中的数据-->
    <div ng-controller="FirstCtrl">
        <h1>{{data.message + " World!"}}</h1>
    </div>

    <!-- 以下表达式不会输出任何内容,因为它在FirstCtrl之外-->
    <p>下面的内容不会显示</p>
    <p>{{data.message}}</p>
    <script type="text/JavaScript" src="components/angular/angular.js"></script>
    <script type="text/javascript" src="js/app.js"></script>
</body>

非常明显,我们定义了controller,所以在controller 范围里面的内容,才受响应的$scope 管理

要注意,使用controller 以后,那么不在controller 里面的内容就不受 {{…}} 表达式的控制

其次,不用controller 也可以使用$scope 并在全局使用,但是不推荐

Data-Binding ng-model

双向绑定来了

在上文的基础上,修改index.html

   <div ng-controller="FirstCtrl">
        <h1>{{data.message + " World!"}}</h1>
        <input type="text" ng-model="data.message">
        <input type="button" value="test" ng-click="test()">
    </div>

和Vue 很像,通过ng-model 这个属性去绑定ng 里的值,做到双向绑定

不仅如此,还可以在$scope 上添加方法,例如 $scope.test = function(){...},就有一个 test 函数可以调用,绑定在ng-click 属性上

Conditional ng-if / ng-show / ng-hide

    <!-- 如果data.flag == true,则显示此段文字-->
    <div ng-if="data.flag">
        <p>ng-if中的文字</p>
    </div>

    <!-- 如果data.flag == true,则显示此段文字-->
    <div ng-show="data.flag">
        <p>ng-show中的文字</p>
    </div>

    <!-- 如果data.flag == false,则显示此段文字-->
    <div ng-hide="data.flag">
        <p>ng-hide中的文字</p>
    </div>

和Vue 基本相同

ng-if 会删除整个元素,而ng-show / ng-hide 只使用css 隐藏&现实

Loop ng-repeat

   $scope.list = [
     {name: "Harry"},
     {name: "Tom"},
     {name: "Jerry"},
     {name: "Harry"},
    ];
        <ul>
            <li ng-repeat="item in list">
                {{ item.name }} is No.{{ $index }}
            </li>
        </ul>

和Vue相同,其中{{ $index }} 一直在一个loop 中存在,表示index

Filter

{{ 1234 | number:2 }}
//显示两位小数,结果 1,234.00

{{ 1234.56 | currency:"人民币¥":0}}
//转化为货币后输出(保留0位小数,四舍五入),结果为
//人民币¥1,234.00

{{ list | json }}
//将对象转化为json文本输出,结果为
//[ { "name": "Harry" }, { "name": "Tom" }, { "name": "Jerry" } ]

<tr ng-repeat="x in list | orderBy:'name'">
//对显示的数据列表按照name进行排序
//结果为显示顺序Harry,Jerry,Tom

自定义Filter

//app.js
App.filter("reverse", function(){
    return function(text){
        return text.split("").reverse().join("");
    }
});

Filter 还被用作小数量级的搜索功能

Search Name:<input type="text" ng-model="searchText">
<ul>
    <li ng-repeat="item in list | filter:searchText">
        {{ item.name }} is No.{{ $index }}
    </li>
</ul>

Toggle Class ng-class

<p ng-class="{strike: deleted, bold: important, 'has-error': error}">示例文字</p>
$scope.styleClass = {
    deleted: false,
    important: false,
    error: false
};
.strike {},
.bold {},
.has-error {}

甚至可以用直接写class 的方式

    <p ng-class="data.style">直接使用字符串作为样式</p>
    <input type="text" ng-model="data.style">
//or
	<p ng-class="[data.style, {orange: warning}]">同时应用两种样式</p>

ng-style 同样也可以修改样式,例如一般的inline-style

<span ng-style="{'background-color':colorInput}">示例文本</span>
//colorInput为$scope中的对象,传入文本即可

<span ng-style="styleText">示例文本</span>
//styleText为样式为 '{'color':red}'类型的文本,甚至可以传函数

Angular 专门提供了一个属性去做下拉列表

    $scope.colors = [
        {name: '黑色', color:'black' },
        {name: '白色', color:'white' },
        {name: '红色', color:'red' },
        {name: '蓝色', color:'blue' },
        {name: '黄色', color:'yellow'}
    ];

    $scope.colorChosen = $scope.colors[0];
        <label>选择一个颜色(无空选项):
            <select ng-model="colorChosen" ng-options="color.name for color in colors">

            </select>
        </label>
        <br>

        当前选中的颜色: {{ colorChosen.name }}
        <div style="border:solid 1px black; height:20px"
             ng-style="{'background-color':colorChosen.color}">
        </div>

Template ng-include & ng-template

ng-include

<!--  直接传入一个网页的地址,请注意这里的使用用法 -->
<!--  'view/part.html' 外部有单引号 -->
<div ng-include="'views/part.html'"></div>

<!-- 假设$scope中有template:{url:"http://..."}这个对象 -->
<div ng-include="template.url"></div>

<div ng-include="getUrl()"></div>

<!-- 另外,ng-include的用法也可以直接作为标签名使用 -->
<div data-ng-include="'views/part.html'"></div>
<ng-include src="'views/part.html'"></ng-include>

ng-template

<script type="text/ng-template" id="html_part.html">
  <!-- HTML片段的实际内容 -->
</script>
<div ng-include="'html_part.html'"></div>

Directive

Basic Usage

var App = angular.module("App", []);

App.directive("people", function(){
    return {
        restrict: "E",
        replace : true,
        template : "<p>姓名:{{data.name}}</p><p>性别:{{data.sex}}</p>"
    }
});

App.controller("FirstCtrl", function ($scope) {
    $scope.data = {
        name: "Harry",
        sex : "男"
    };
});
<div ng-controller="FirstCtrl">
    <!-- 注意这里只加入了一个people的标签 -->
    <people></people>
</div>
  • directive 第一个参数是directive 名,使用驼峰命名;第二个参数是config,包含如下
  • Restrict 定义了使用方式
    • E: Element, <people></people>
    • A: Attribute, <div people> </div>
    • C: Class, <div class="people"> </div>
    • EAC: all accept
  • replace 开启后,在生成的HTML 里会用正常标签而不是<people>
  • Template 定义了模版

带参数的directive

App.directive("people", function(){
    return {
        restrict: "A",
        scope:{
            info: "="
        },
        template : "<p>姓名:{{info.name}}</p><p>性别:{{info.sex}}</p>"
    }
});

App.controller("FirstCtrl", function ($scope) {
    $scope.harry = {
        name: "Harry",
        sex : "男"
    };
});
<div ng-controller="FirstCtrl">
    <div people info="harry"></div>
</div>

传入了一个info,使用scope 属性接住

scope 属性是这个directive 自己的$scope,当值等于 “=” 时表示要从HTML中获取名为info 的属性值

要注意的是,这里的harry 是一个object,所以 “=” 传入的是object

如果需要直传字符串,那么需要用 info: "@"

总结如下:

  • info: “=” 传入object
  • info: “@” 传入string
  • info: “&” 传入fallback

Transclude

与vue中的slot 相同

App.directive("formDirective", function () {
    return {
        restrict: "A",        
        //通过transclude标签将Directive变为一个容器
        transclude: true,
        //注意template中的ng-transclude,这里是放置原有代码的地方。
        template: "<h1>标题</h1><p>这里是段落文字</p><div ng-transclude></div>"
    }
});
<div ng-controller="FirstCtrl">
    <div form-directive>
        <p>这段文字是放置在Directive中间的。</p>
    </div>
</div>

首先要声明 transclude 属性为true,其次在template里面用 ng-transclude 嵌入新的HTML

Component

component 是一种比directive更好的选择

angular.
module('phoneList').
component('phoneList', {
    template:
    '<ul>' +
    '<li ng-repeat="phone in $ctrl.phones">' +
    '<span>{{phone.name}}</span>' +
    '<p>{{phone.snippet}}</p>' +
    '</li>' +
    '</ul>',
    controller: function PhoneListController() {
        this.phones = [
            {
                name: 'Nexus S',
                snippet: 'Fast just got faster with Nexus S.'
            }, {
                name: 'Motorola XOOM™ with Wi-Fi',
                snippet: 'The Next, Next Generation tablet.'
            }, {
                name: 'MOTOROLA XOOM™',
                snippet: 'The Next, Next Generation tablet.'
            }
        ];
    }
});

其实跟directive 很像,但是内部包括一个controller 自己定义scope data

此外,每一个compoent 应该有自己的angular.module,这样才能最大化的实现复用。

在上面的代码里,这个phonelist 有自己的module phoneList,所以在app.js 中,应该写成如下

// Define the `phonecatApp` module
angular.module('phonecatApp', [
  // ...which depends on the `phoneList` module
  'phoneList'
]);